import { consoleUtils } from "../../common/utils/consoleUtils"
import { bufferUtils } from "../utils/bufferUtils"

export const __MESSAGE_TYPE_BUFFER_SIZE__ = 10

export class StringMessageDistributor {
  private listeners: (Array<(message: string) => void>) = []

  subscribe(handle: (message: string) => void) {
    this.listeners.push(handle)
    return () => {
      this.listeners.splice(this.listeners.findIndex(l => l === handle), 1)
    }
  }

  notify(message: string) {
    this.listeners.forEach(l => l(message))
  }

  distribute(value: string) {
    try {
      console.log('StringMessageDistributor.ts -> distributeBuffer -> value: ', value)
      this.notify(value)
    } catch (err) {
      consoleUtils.error('StringMessageDistributor.ts -> distributeBuffer -> error: ', err)
    }
  }

  distributeBuffer(value: ArrayBuffer) {
    try {
      console.log('StringMessageDistributor.ts -> distributeBuffer -> value: ', value)
      let buffer = value.slice(__MESSAGE_TYPE_BUFFER_SIZE__)
      let message = bufferUtils.bufferToStr(buffer)
      this.notify(message)
    } catch (err) {
      consoleUtils.error('StringMessageDistributor.ts -> distributeBuffer -> error: ', err)
    }
  }

  sendListeners: (Array<(message: string) => Promise<void>>) = []

  subscribeSend(sendListener: (message: string) => Promise<void>) {
    this.sendListeners.push(sendListener)
    return () => {
      this.sendListeners.splice(this.sendListeners.findIndex(l => l === sendListener), 1)
    }
  }

  async notifySend(message: string) {
    this.sendListeners.forEach(async l => {
      await l(message)
    })
  }

  async send(message: string) {
    const stringMessage = 'string'.padEnd(__MESSAGE_TYPE_BUFFER_SIZE__, ' ') + message
    await this.notifySend(stringMessage)
  }
}

export const stringMessageDistributor = new StringMessageDistributor()